package com.yjb.tenet.boot.quartz.application.manager;

import com.yjb.tenet.boot.common.constants.GlobalConstants;
import com.yjb.tenet.boot.quartz.application.service.SysJobService;
import com.yjb.tenet.boot.quartz.domain.entity.SysJob;
import com.yjb.tenet.boot.quartz.domain.form.SysJobAddForm;
import com.yjb.tenet.boot.quartz.domain.form.SysJobEditForm;
import com.yjb.tenet.boot.quartz.domain.form.SysJobStatusForm;
import com.yjb.tenet.boot.quartz.infrastructure.constants.ScheduleConstants;
import com.yjb.tenet.boot.quartz.infrastructure.utils.ScheduleUtils;
import com.yjb.tenet.boot.system.infrastructure.enums.FlagEnums;
import org.quartz.JobDataMap;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;

/**
 * @Description
 * @Author yin.jinbiao
 * @Date 2022/5/4 20:19
 * @Version 1.0
 */
@Component
public class SysJobManager {

    @Resource
    private Scheduler scheduler;

    @Resource
    private SysJobService sysJobService;

	/**
	 * 项目启动时，初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理（注：不能手动修改数据库ID和任务组名，否则会导致脏数据）
	 */
	@PostConstruct
	public void init() throws SchedulerException {
		scheduler.clear();
		List<SysJob> jobList = sysJobService.lambdaQuery().eq(SysJob::getDeleted, GlobalConstants.NOT_DELETED).list();
		for (SysJob job : jobList) {
			ScheduleUtils.createScheduleJob(scheduler, job);
		}
	}

	/**
	 * 创建任务
	 * @param sysJobAddForm
	 * @throws SchedulerException
	 */
	@Transactional(rollbackFor = Exception.class)
	public void createJob(SysJobAddForm sysJobAddForm) throws SchedulerException {
		SysJob sysJob = new SysJob();
		BeanUtils.copyProperties(sysJobAddForm, sysJob);
		sysJobService.save(sysJob);
		ScheduleUtils.createScheduleJob(scheduler, sysJob);
	}

	/**
	 * 修改任务
	 * @param sysJobEditForm
	 * @throws SchedulerException
	 */
	@Transactional(rollbackFor = Exception.class)
	public void updateJob(SysJobEditForm sysJobEditForm) throws SchedulerException {
		SysJob oldOne = sysJobService.getById(sysJobEditForm.getId());
		BeanUtils.copyProperties(sysJobEditForm, oldOne);
		sysJobService.updateById(oldOne);
		// 判断是否存在
		JobKey jobKey = ScheduleUtils.getJobKey(oldOne.getId(), oldOne.getJobGroup());
		if (scheduler.checkExists(jobKey)) {
			// 防止创建时存在数据问题 先移除，然后在执行创建操作
			scheduler.deleteJob(jobKey);
		}
		ScheduleUtils.createScheduleJob(scheduler, oldOne);
	}

	/**
	 * 修改任务状态
	 * @param sysJobStatusForm
	 * @throws SchedulerException
	 */
	@Transactional(rollbackFor = Exception.class)
	public void changeStatus(SysJobStatusForm sysJobStatusForm) throws SchedulerException {
		SysJob job = sysJobService.getById(sysJobStatusForm.getId());
		job.setPause(sysJobStatusForm.getPause());
		sysJobService.updateById(job);
		if (FlagEnums.NO.getValue().equals(job.getPause())) {
			scheduler.resumeJob(ScheduleUtils.getJobKey(job.getId(), job.getJobGroup()));
		}
		else if (FlagEnums.YES.getValue().equals(job.getPause())){
			scheduler.pauseJob(ScheduleUtils.getJobKey(job.getId(), job.getJobGroup()));
		}
	}


	/**
	 * 立即执行该任务
	 * @param id
	 * @throws SchedulerException
	 */
	public void run(Long id) throws SchedulerException {
		SysJob sysJob = sysJobService.getById(id);
		// 参数
		JobDataMap dataMap = new JobDataMap();
		dataMap.put(ScheduleConstants.TASK_PROPERTIES, sysJob);
		scheduler.triggerJob(ScheduleUtils.getJobKey(sysJob.getId(), sysJob.getJobGroup()), dataMap);
	}

	/**
	 * 删除任务
	 * @param id
	 * @throws SchedulerException
	 */
	public void deleteJob(Long id) throws SchedulerException {
		SysJob sysJob = sysJobService.getById(id);
		sysJob.setDeleted(sysJob.getId());
		sysJobService.updateById(sysJob);
		scheduler.deleteJob(ScheduleUtils.getJobKey(sysJob.getId(), sysJob.getJobGroup()));
	}

}
